home *** CD-ROM | disk | FTP | other *** search
- Date: Wed, 13 Mar 85 16:58:41 pst
- From: decvax!ucbvax!UCBJADE!ucbjade:mwm (Mike Meyer)
- Subject: XLISP 1.4 part 4 (of 4)
-
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # Makefile
- # fact.lsp
- # init.lsp
- # object.lsp
- # prolog.lsp
- # trace.lsp
- # xlbind.c
- # xldbug.c
- # xlisp.h
- # xlsetf.c
- # xlstr.c
- # xlstub.c.XXX
- # xlsubr.c
- # xlsym.c
- # xlsys.c
- # This archive created: Mon Dec 2 10:01:12 1985
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'Makefile'" '(921 characters)'
- if test -f 'Makefile'
- then
- echo shar: will not over-write existing file "'Makefile'"
- else
- sed 's/^X//' << \SHAR_EOF > 'Makefile'
- XSRC1= xlobj.c xllist.c xlcont.c xlbfun.c
- XSRC2= xldmem.c xleval.c xlfio.c xlftab.c xlglob.c xlio.c xlisp.c xljump.c \
- xlmath.c xlprin.c xlread.c xlinit.c
- XSRC3= xlsetf.c xlstr.c xlsubr.c xlsym.c xlsys.c xlbind.c xldbug.c
- XSRCS= $(SRC1) $(SRC2) $(SRC3) xlisp.h
-
- OBJS= xlbfun.o xlbind.o xlcont.o xldbug.o xldmem.o xleval.o xlfio.o \
- xlftab.o xlglob.o xlinit.o xlio.o xlisp.o xljump.o xllist.o xlmath.o \
- xlobj.o xlprin.o xlread.o xlsetf.o xlstr.o xlsubr.o xlsym.o xlsys.o
- MISC= Makefile fact.lsp init.lsp object.lsp prolog.lsp trace.lsp \
- xlstub.c.NOTUSED
-
- CFLAGS= -O
-
- xlisp: $(OBJS)
- cc -o xlisp $(CFLAGS) $(OBJS)
-
- $(OBJS): xlisp.h
-
- rcs: $(SRCS)
- rcs -l $?
- touch rcs
-
- lint:
- lint -ach $(SRCS)
-
- new: clean
- rm -f xlisp
- make xlisp
-
- clean:
- rm -f *.o
-
- shar: $(SRCS) $(MISC)
- shar -c -v xlisp.doc > xlisp1.shar
- shar -c -v $(SRC1) > xlisp2.shar
- shar -c -v $(SRC2) > xlisp3.shar
- shar -c -v $(SRC3) $(MISC) > xlisp4.shar
- SHAR_EOF
- if test 921 -ne "`wc -c < 'Makefile'`"
- then
- echo shar: error transmitting "'Makefile'" '(should have been 921 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'fact.lsp'" '(84 characters)'
- if test -f 'fact.lsp'
- then
- echo shar: will not over-write existing file "'fact.lsp'"
- else
- sed 's/^X//' << \SHAR_EOF > 'fact.lsp'
- (defun factorial (n)
- (cond ((= n 1) 1)
- (t (* n (factorial (- n 1))))))
- SHAR_EOF
- if test 84 -ne "`wc -c < 'fact.lsp'`"
- then
- echo shar: error transmitting "'fact.lsp'" '(should have been 84 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'init.lsp'" '(1959 characters)'
- if test -f 'init.lsp'
- then
- echo shar: will not over-write existing file "'init.lsp'"
- else
- sed 's/^X//' << \SHAR_EOF > 'init.lsp'
- ; get some more memory
- (expand 1)
-
- ; some fake definitions for Common Lisp pseudo compatiblity
- (setq symbol-function symbol-value)
- (setq fboundp boundp)
- (setq first car)
- (setq second cadr)
- (setq rest cdr)
-
- ; some more cxr functions
- (defun caddr (x) (car (cddr x)))
- (defun cadddr (x) (cadr (cddr x)))
-
- ; (when test code...) - execute code when test is true
- (defmacro when (test &rest code)
- `(cond (,test ,@code)))
-
- ; (unless test code...) - execute code unless test is true
- (defmacro unless (test &rest code)
- `(cond ((not ,test) ,@code)))
-
- ; (makunbound sym) - make a symbol be unbound
- (defun makunbound (sym) (setq sym '*unbound*) sym)
-
- ; (objectp expr) - object predicate
- (defun objectp (x) (eq (type x) 'OBJ))
-
- ; (filep expr) - file predicate
- (defun filep (x) (eq (type x) 'FPTR))
-
- ; (unintern sym) - remove a symbol from the oblist
- (defun unintern (sym) (cond ((member sym *oblist*)
- (setq *oblist* (delete sym *oblist*))
- t)
- (t nil)))
-
- ; (mapcan ...)
- (defmacro mapcan (&rest args) `(apply #'nconc (mapcar ,@args)))
-
- ; (mapcon ...)
- (defmacro mapcon (&rest args) `(apply #'nconc (maplist ,@args)))
-
- ; (save fun) - save a function definition to a file
- (defun save (fun)
- (let* ((fname (strcat (symbol-name fun) ".lsp"))
- (fp (openo fname)))
- (cond (fp (print (cons (if (eq (car (eval fun)) 'lambda)
- 'defun
- 'defmacro)
- (cons fun (cdr (eval fun)))) fp)
- (close fp)
- fname)
- (t nil))))
-
- ; (debug) - enable debug breaks
- (defun debug ()
- (setq *breakenable* t))
-
- ; (nodebug) - disable debug breaks
- (defun nodebug ()
- (setq *breakenable* nil))
-
- ; initialize to enable breaks but no trace back
- (setq *breakenable* t)
- (setq *tracenable* nil)
- SHAR_EOF
- if test 1959 -ne "`wc -c < 'init.lsp'`"
- then
- echo shar: error transmitting "'init.lsp'" '(should have been 1959 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'object.lsp'" '(2374 characters)'
- if test -f 'object.lsp'
- then
- echo shar: will not over-write existing file "'object.lsp'"
- else
- sed 's/^X//' << \SHAR_EOF > 'object.lsp'
- ; This is an example using the object-oriented programming support in
- ; XLISP. The example involves defining a class of objects representing
- ; dictionaries. Each instance of this class will be a dictionary in
- ; which names and values can be stored. There will also be a facility
- ; for finding the values associated with names after they have been
- ; stored.
-
- ; Create the 'Dictionary' class.
-
- (setq Dictionary (Class 'new))
-
- ; Establish the instance variables for the new class.
- ; The variable 'entries' will point to an association list representing the
- ; entries in the dictionary instance.
-
- (Dictionary 'ivars '(entries))
-
- ; Setup the method for the 'isnew' initialization message.
- ; This message will be send whenever a new instance of the 'Dictionary'
- ; class is created. Its purpose is to allow the new instance to be
- ; initialized before any other messages are sent to it. It sets the value
- ; of 'entries' to nil to indicate that the dictionary is empty.
-
- (Dictionary 'answer 'isnew '()
- '((setq entries nil)
- self))
-
- ; Define the message 'add' to make a new entry in the dictionary. This
- ; message takes two arguments. The argument 'name' specifies the name
- ; of the new entry; the argument 'value' specifies the value to be
- ; associated with that name.
-
- (Dictionary 'answer 'add '(name value)
- '((setq entries
- (cons (cons name value) entries))
- value))
-
- ; Create an instance of the 'Dictionary' class. This instance is an empty
- ; dictionary to which words may be added.
-
- (setq d (Dictionary 'new))
-
- ; Add some entries to the new dictionary.
-
- (d 'add 'mozart 'composer)
- (d 'add 'winston 'computer-scientist)
-
- ; Define a message to find entries in a dictionary. This message takes
- ; one argument 'name' which specifies the name of the entry for which to
- ; search. It returns the value associated with the entry if one is
- ; present in the dictionary. Otherwise, it returns nil.
-
- (Dictionary 'answer 'find '(name &aux entry)
- '((cond ((setq entry (assoc name entries))
- (cdr entry))
- (t
- nil))))
-
- ; Try to find some entries in the dictionary we created.
-
- (d 'find 'mozart)
- (d 'find 'winston)
- (d 'find 'bozo)
-
- ; The names 'mozart' and 'winston' are found in the dictionary so their
- ; values 'composer' and 'computer-scientist' are returned. The name 'bozo'
- ; is not found so nil is returned in this case.
- SHAR_EOF
- if test 2374 -ne "`wc -c < 'object.lsp'`"
- then
- echo shar: error transmitting "'object.lsp'" '(should have been 2374 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'prolog.lsp'" '(4289 characters)'
- if test -f 'prolog.lsp'
- then
- echo shar: will not over-write existing file "'prolog.lsp'"
- else
- sed 's/^X//' << \SHAR_EOF > 'prolog.lsp'
-
- ;; The following is a tiny Prolog interpreter in MacLisp
- ;; written by Ken Kahn and modified for XLISP by David Betz.
- ;; It was inspired by other tiny Lisp-based Prologs of
- ;; Par Emanuelson and Martin Nilsson.
- ;; There are no side-effects anywhere in the implementation.
- ;; Though it is VERY slow of course.
-
- (defun prolog (database &aux goal)
- (do () ((not (progn (princ "Query?") (setq goal (read)))))
- (prove (list (rename-variables goal '(0)))
- '((bottom-of-environment))
- database
- 1)))
-
- ;; prove - proves the conjunction of the list-of-goals
- ;; in the current environment
-
- (defun prove (list-of-goals environment database level)
- (cond ((null list-of-goals) ;; succeeded since there are no goals
- (print-bindings environment environment)
- (not (y-or-n-p "More?")))
- (t (try-each database database
- (cdr list-of-goals) (car list-of-goals)
- environment level))))
-
- (defun try-each (database-left database goals-left goal environment level
- &aux assertion new-enviroment)
- (cond ((null database-left) nil) ;; fail since nothing left in database
- (t (setq assertion
- (rename-variables (car database-left)
- (list level)))
- (setq new-environment
- (unify goal (car assertion) environment))
- (cond ((null new-environment) ;; failed to unify
- (try-each (cdr database-left) database
- goals-left goal
- environment level))
- ((prove (append (cdr assertion) goals-left)
- new-environment
- database
- (+ 1 level)))
- (t (try-each (cdr database-left) database
- goals-left goal
- environment level))))))
-
- (defun unify (x y environment &aux new-environment)
- (setq x (value x environment))
- (setq y (value y environment))
- (cond ((variable-p x) (cons (list x y) environment))
- ((variable-p y) (cons (list y x) environment))
- ((or (atom x) (atom y))
- (cond ((equal x y) environment)
- (t nil)))
- (t (setq new-environment (unify (car x) (car y) environment))
- (cond (new-environment (unify (cdr x) (cdr y) new-environment))
- (t nil)))))
-
- (defun value (x environment &aux binding)
- (cond ((variable-p x)
- (setq binding (assoc x environment))
- (cond ((null binding) x)
- (t (value (cadr binding) environment))))
- (t x)))
-
- (defun variable-p (x)
- (and x (listp x) (eq (car x) '?)))
-
- (defun rename-variables (term list-of-level)
- (cond ((variable-p term) (append term list-of-level))
- ((atom term) term)
- (t (cons (rename-variables (car term) list-of-level)
- (rename-variables (cdr term) list-of-level)))))
-
- (defun print-bindings (environment-left environment)
- (cond ((cdr environment-left)
- (cond ((= 0 (nth 2 (caar environment-left)))
- (prin1 (cadr (caar environment-left)))
- (princ " = ")
- (print (value (caar environment-left) environment))))
- (print-bindings (cdr environment-left) environment))))
-
- ;; a sample database:
- (setq db '(((father madelyn ernest))
- ((mother madelyn virginia))
- ((father david arnold))
- ((mother david pauline))
- ((father rachel david))
- ((mother rachel madelyn))
- ((grandparent (? grandparent) (? grandchild))
- (parent (? grandparent) (? parent))
- (parent (? parent) (? grandchild)))
- ((parent (? parent) (? child))
- (mother (? parent) (? child)))
- ((parent (? parent) (? child))
- (father (? parent) (? child)))))
-
- ;; the following are utilities
- (defun y-or-n-p (prompt)
- (princ prompt)
- (eq (read) 'y))
-
- ;; start things going
- (prolog db)
- SHAR_EOF
- if test 4289 -ne "`wc -c < 'prolog.lsp'`"
- then
- echo shar: error transmitting "'prolog.lsp'" '(should have been 4289 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'trace.lsp'" '(642 characters)'
- if test -f 'trace.lsp'
- then
- echo shar: will not over-write existing file "'trace.lsp'"
- else
- sed 's/^X//' << \SHAR_EOF > 'trace.lsp'
- (setq *tracelist* nil)
-
- (defun evalhookfcn (expr &aux val)
- (if (and (consp expr) (member (car expr) *tracelist*))
- (progn (princ ">>> ") (print expr)
- (setq val (evalhook expr evalhookfcn nil))
- (princ "<<< ") (print val))
- (evalhook expr evalhookfcn nil)))
-
- (defun trace (fun)
- (if (not (member fun *tracelist*))
- (progn (setq *tracelist* (cons fun *tracelist*))
- (setq *evalhook* evalhookfcn)))
- *tracelist*)
-
- (defun untrace (fun)
- (if (null (setq *tracelist* (delete fun *tracelist*)))
- (setq *evalhook* nil))
- *tracelist*)
- SHAR_EOF
- if test 642 -ne "`wc -c < 'trace.lsp'`"
- then
- echo shar: error transmitting "'trace.lsp'" '(should have been 642 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'xlbind.c'" '(1509 characters)'
- if test -f 'xlbind.c'
- then
- echo shar: will not over-write existing file "'xlbind.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'xlbind.c'
- /* xlbind - xlisp symbol binding routines */
-
- #include "xlisp.h"
-
- /* external variables */
- extern NODE *xlenv,*xlnewenv;
-
- /* xlsbind - bind a value to a symbol sequentially */
- xlsbind(sym,val)
- NODE *sym,*val;
- {
- NODE *ptr;
-
- /* create a new environment list entry */
- ptr = newnode(LIST);
- rplacd(ptr,xlenv);
- xlenv = ptr;
-
- /* create a new variable binding */
- rplaca(ptr,newnode(LIST));
- rplaca(car(ptr),sym);
- rplacd(car(ptr),sym->n_symvalue);
- sym->n_symvalue = val;
- }
-
- /* xlbind - bind a value to a symbol in parallel */
- xlbind(sym,val)
- NODE *sym,*val;
- {
- NODE *ptr;
-
- /* create a new environment list entry */
- ptr = newnode(LIST);
- rplacd(ptr,xlnewenv);
- xlnewenv = ptr;
-
- /* create a new variable binding */
- rplaca(ptr,newnode(LIST));
- rplaca(car(ptr),sym);
- rplacd(car(ptr),val);
- }
-
- /* xlfixbindings - make a new set of bindings visible */
- xlfixbindings()
- {
- NODE *eptr,*bnd,*sym,*oldvalue;
-
- /* fix the bound value of each symbol in the environment chain */
- for (eptr = xlnewenv; eptr != xlenv; eptr = cdr(eptr)) {
- bnd = car(eptr);
- sym = car(bnd);
- oldvalue = sym->n_symvalue;
- sym->n_symvalue = cdr(bnd);
- rplacd(bnd,oldvalue);
- }
- xlenv = xlnewenv;
- }
-
- /* xlunbind - unbind symbols bound in this environment */
- xlunbind(env)
- NODE *env;
- {
- NODE *bnd;
-
- /* unbind each symbol in the environment chain */
- for (; xlenv != env; xlenv = cdr(xlenv))
- if (bnd = car(xlenv))
- car(bnd)->n_symvalue = cdr(bnd);
- }
- SHAR_EOF
- if test 1509 -ne "`wc -c < 'xlbind.c'`"
- then
- echo shar: error transmitting "'xlbind.c'" '(should have been 1509 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'xldbug.c'" '(3924 characters)'
- if test -f 'xldbug.c'
- then
- echo shar: will not over-write existing file "'xldbug.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'xldbug.c'
- /* xldebug - xlisp debugging support */
-
- #include "xlisp.h"
-
- /* external variables */
- extern long total;
- extern int xldebug;
- extern int xltrace;
- extern NODE *s_unbound;
- extern NODE *s_stdin,*s_stdout;
- extern NODE *s_tracenable,*s_tlimit,*s_breakenable;
- extern NODE *s_continue,*s_quit;
- extern NODE *xlstack;
- extern NODE *true;
- extern NODE **trace_stack;
-
- /* external routines */
- extern char *malloc();
-
- /* forward declarations */
- XFORWARD NODE *stacktop();
-
- /* xlfail - xlisp error handler */
- xlfail(emsg)
- char *emsg;
- {
- xlerror(emsg,stacktop());
- }
-
- /* xlabort - xlisp serious error handler */
- xlabort(emsg)
- char *emsg;
- {
- xlsignal(emsg,s_unbound);
- }
-
- /* xlbreak - enter a break loop */
- xlbreak(emsg,arg)
- char *emsg; NODE *arg;
- {
- breakloop("break",NULL,emsg,arg,TRUE);
- }
-
- /* xlerror - handle a fatal error */
- xlerror(emsg,arg)
- char *emsg; NODE *arg;
- {
- doerror(NULL,emsg,arg,FALSE);
- }
-
- /* xlcerror - handle a recoverable error */
- xlcerror(cmsg,emsg,arg)
- char *cmsg,*emsg; NODE *arg;
- {
- doerror(cmsg,emsg,arg,TRUE);
- }
-
- /* xlerrprint - print an error message */
- xlerrprint(hdr,cmsg,emsg,arg)
- char *hdr,*cmsg,*emsg; NODE *arg;
- {
- printf("%s: %s",hdr,emsg);
- if (arg != s_unbound) { printf(" - "); stdprint(arg); }
- else printf("\n");
- if (cmsg) printf("if continued: %s\n",cmsg);
- }
-
- /* doerror - handle xlisp errors */
- LOCAL doerror(cmsg,emsg,arg,cflag)
- char *cmsg,*emsg; NODE *arg; int cflag;
- {
- /* make sure the break loop is enabled */
- if (s_breakenable->n_symvalue == NIL)
- xlsignal(emsg,arg);
-
- /* call the debug read-eval-print loop */
- breakloop("error",cmsg,emsg,arg,cflag);
- }
-
- /* breakloop - the debug read-eval-print loop */
- LOCAL int breakloop(hdr,cmsg,emsg,arg,cflag)
- char *hdr,*cmsg,*emsg; NODE *arg; int cflag;
- {
- NODE *oldstk,expr,*val;
- CONTEXT cntxt;
-
- /* increment the debug level */
- xldebug++;
-
- /* flush the input buffer */
- xlflush();
-
- /* print the error message */
- xlerrprint(hdr,cmsg,emsg,arg);
-
- /* do the back trace */
- if (s_tracenable->n_symvalue) {
- val = s_tlimit->n_symvalue;
- xlbaktrace(fixp(val) ? val->n_int : -1);
- }
-
- /* create a new stack frame */
- oldstk = xlsave(&expr,NULL);
-
- /* debug command processing loop */
- xlbegin(&cntxt,CF_ERROR,true);
- while (TRUE) {
-
- /* setup the continue trap */
- if (setjmp(cntxt.c_jmpbuf)) {
- xlflush();
- continue;
- }
-
- /* read an expression and check for eof */
- if (!xlread(s_stdin->n_symvalue,&expr.n_ptr)) {
- expr.n_ptr = s_quit;
- break;
- }
-
- /* check for commands */
- if (expr.n_ptr == s_continue) {
- if (cflag) break;
- else xlabort("this error can't be continued");
- }
- else if (expr.n_ptr == s_quit)
- break;
-
- /* evaluate the expression */
- expr.n_ptr = xleval(expr.n_ptr);
-
- /* print it */
- xlprint(s_stdout->n_symvalue,expr.n_ptr,TRUE);
- xlterpri(s_stdout->n_symvalue);
- }
- xlend(&cntxt);
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* decrement the debug level */
- xldebug--;
-
- /* continue the next higher break loop on quit */
- if (expr.n_ptr == s_quit)
- xlsignal("quit from break loop",s_unbound);
- }
-
- /* tpush - add an entry to the trace stack */
- xltpush(nptr)
- NODE *nptr;
- {
- if (++xltrace < TDEPTH)
- trace_stack[xltrace] = nptr;
- }
-
- /* tpop - pop an entry from the trace stack */
- xltpop()
- {
- xltrace--;
- }
-
- /* stacktop - return the top node on the stack */
- LOCAL NODE *stacktop()
- {
- return (xltrace >= 0 && xltrace < TDEPTH ? trace_stack[xltrace] : s_unbound);
- }
-
- /* baktrace - do a back trace */
- xlbaktrace(n)
- int n;
- {
- int i;
-
- for (i = xltrace; (n < 0 || n--) && i >= 0; i--)
- if (i < TDEPTH)
- stdprint(trace_stack[i]);
- }
-
- /* xldinit - debug initialization routine */
- xldinit()
- {
- if ((trace_stack = (NODE **) malloc(TSTKSIZE)) == NULL)
- xlabort("insufficient memory");
- total += (long) TSTKSIZE;
- xltrace = -1;
- xldebug = 0;
- }
- SHAR_EOF
- if test 3924 -ne "`wc -c < 'xldbug.c'`"
- then
- echo shar: error transmitting "'xldbug.c'" '(should have been 3924 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'xlisp.h'" '(8406 characters)'
- if test -f 'xlisp.h'
- then
- echo shar: will not over-write existing file "'xlisp.h'"
- else
- sed 's/^X//' << \SHAR_EOF > 'xlisp.h'
- #include <stdio.h>
-
- /* xlisp - a small subset of lisp */
-
-
- /* system specific definitions */
-
- /* DEFEXT define to enable default extension of '.lsp' on 'load' */
- /* FGETNAME define if system supports 'fgetname' */
- /* NNODES number of nodes to allocate in each request */
- /* xlisp - a small subset of lisp */
-
- /* system specific definitions */
- #define UNIX
-
- #ifdef AZTEC
- #include "stdio.h"
- #include "setjmp.h"
- #else
- #include <stdio.h>
- #include <setjmp.h>
- #include <ctype.h>
- #endif
-
- /* NNODES number of nodes to allocate in each request */
- /* TDEPTH trace stack depth */
- /* FORWARD type of a forward declaration (usually "") */
- /* LOCAL type of a local function (usually "static") */
-
- /* for the Computer Innovations compiler */
- #ifdef CI
- #define NNODES 1000
- #define TDEPTH 500
- #endif
-
- /* for the CPM68K compiler */
- #ifdef CPM68K
- #define NNODES 1000
- #define TDEPTH 500
- #define LOCAL
- #define AFMT "%lx"
- #undef NULL
- #define NULL (char *)0
- #endif
-
- /* for the DeSmet compiler */
- #ifdef DESMET
- #define NNODES 1000
- #define TDEPTH 500
- #define LOCAL
- #define getc(fp) getcx(fp)
- #define putc(ch,fp) putcx(ch,fp)
- #define EOF -1
- #endif
-
- /* for the MegaMax compiler */
- #ifdef MEGAMAX
- #define NNODES 200
- #define TDEPTH 100
- #define LOCAL
- #define AFMT "%lx"
- #define TSTKSIZE (4 * TDEPTH)
- #endif
-
- /* for the VAX-11 C compiler */
- #ifdef vms
- #define NNODES 2000
- #define TDEPTH 1000
- #endif
-
- /* for the DECUS C compiler */
- #ifdef decus
- #define NNODES 200
- #define TDEPTH 100
- #define FORWARD extern
- #endif
-
- /* for unix compilers */
- #ifdef unix
- #define NNODES 200
- #define TDEPTH 100
- #endif
-
- /* for the AZTEC C compiler */
- #ifdef AZTEC
- #define NNODES 200
- #define TDEPTH 100
- #define getc(fp) agetc(fp)
- #define putc(ch,fp) aputc(ch,fp)
- #endif
-
- /* default important definitions */
- #ifndef NNODES
- #define NNODES 200
- #endif
- #ifndef TDEPTH
- #define TDEPTH 100
- #endif
- #ifndef FORWARD
- #define FORWARD
- #endif
- #ifndef LOCAL
- #define LOCAL static
- #endif
- #ifndef AFMT
- #define AFMT "%x"
- #endif
- #ifndef TSTKSIZE
- #define TSTKSIZE (sizeof(NODE *) * TDEPTH)
- #endif
-
- /* useful definitions */
- #define TRUE 1
- #define FALSE 0
- #define NIL (NODE *)0
-
- /* program limits */
- #define STRMAX 100 /* maximum length of a string constant */
-
- /* node types */
- #define FREE 0
- #define SUBR 1
- #define FSUBR 2
- #define LIST 3
- #define SYM 4
- #define INT 5
- #define STR 6
- #define OBJ 7
- #define FPTR 8
-
- /* node flags */
- #define MARK 1
- #define LEFT 2
-
- /* string types */
- #define DYNAMIC 0
- #define STATIC 1
-
- /* new node access macros */
- #define ntype(x) ((x)->n_type)
- #define atom(x) ((x) == NIL || (x)->n_type != LIST)
- #define null(x) ((x) == NIL)
- #define listp(x) ((x) == NIL || (x)->n_type == LIST)
- #define consp(x) ((x) && (x)->n_type == LIST)
- #define subrp(x) ((x) && (x)->n_type == SUBR)
- #define fsubrp(x) ((x) && (x)->n_type == FSUBR)
- #define stringp(x) ((x) && (x)->n_type == STR)
- #define symbolp(x) ((x) && (x)->n_type == SYM)
- #define filep(x) ((x) && (x)->n_type == FPTR)
- #define objectp(x) ((x) && (x)->n_type == OBJ)
- #define fixp(x) ((x) && (x)->n_type == INT)
- #define car(x) ((x)->n_car)
- #define cdr(x) ((x)->n_cdr)
- #define rplaca(x,y) ((x)->n_car = (y))
- #define rplacd(x,y) ((x)->n_cdr = (y))
-
- /* symbol node */
- #define n_symplist n_info.n_xsym.xsy_plist
- #define n_symvalue n_info.n_xsym.xsy_value
-
- /* subr/fsubr node */
- #define n_subr n_info.n_xsubr.xsu_subr
-
- /* list node */
- #define n_car n_info.n_xlist.xl_car
- #define n_cdr n_info.n_xlist.xl_cdr
- #define n_ptr n_info.n_xlist.xl_car
-
- /* integer node */
- #define n_int n_info.n_xint.xi_int
-
- /* string node */
- #define n_str n_info.n_xstr.xst_str
- #define n_strtype n_info.n_xstr.xst_type
-
- /* object node */
- #define n_obclass n_info.n_xobj.xo_obclass
- #define n_obdata n_info.n_xobj.xo_obdata
-
- /* file pointer node */
- #define n_fp n_info.n_xfptr.xf_fp
- #define n_savech n_info.n_xfptr.xf_savech
-
- /* node structure */
- typedef struct node {
- char n_type; /* type of node */
- char n_flags; /* flag bits */
- union { /* value */
- struct xsym { /* symbol node */
- struct node *xsy_plist; /* symbol plist - (name . plist) */
- struct node *xsy_value; /* the current value */
- } n_xsym;
- struct xsubr { /* subr/fsubr node */
- struct node *(*xsu_subr)(); /* pointer to an internal routine */
- } n_xsubr;
- struct xlist { /* list node (cons) */
- struct node *xl_car; /* the car pointer */
- struct node *xl_cdr; /* the cdr pointer */
- } n_xlist;
- struct xint { /* integer node */
- int xi_int; /* integer value */
- } n_xint;
- struct xstr { /* string node */
- int xst_type; /* string type */
- char *xst_str; /* string pointer */
- } n_xstr;
- struct xobj { /* object node */
- struct node *xo_obclass; /* class of object */
- struct node *xo_obdata; /* instance data */
- } n_xobj;
- struct xfptr { /* file pointer node */
- FILE *xf_fp; /* the file pointer */
- int xf_savech; /* lookahead character for input files */
- } n_xfptr;
- } n_info;
- } NODE;
-
- /* execution context flags */
- #define CF_GO 1
- #define CF_RETURN 2
- #define CF_THROW 4
- #define CF_ERROR 8
-
- /* execution context */
- typedef struct context {
- int c_flags; /* context type flags */
- struct node *c_expr; /* expression (type dependant) */
- jmp_buf c_jmpbuf; /* longjmp context */
- struct context *c_xlcontext; /* old value of xlcontext */
- struct node *c_xlstack; /* old value of xlstack */
- struct node *c_xlenv,*c_xlnewenv; /* old values of xlenv and xlnewenv */
- int c_xltrace; /* old value of xltrace */
- } CONTEXT;
-
- /* function table entry structure */
- struct fdef {
- char *f_name; /* function name */
- int f_type; /* function type SUBR/FSUBR */
- struct node *(*f_fcn)(); /* function code */
- };
-
- /* memory segment structure definition */
- struct segment {
- int sg_size;
- struct segment *sg_next;
- struct node sg_nodes[1];
- };
-
- /* external procedure declarations */
- extern struct node *xleval(); /* evaluate an expression */
- extern struct node *xlapply(); /* apply a function to arguments */
- extern struct node *xlevlist(); /* evaluate a list of arguments */
- extern struct node *xlarg(); /* fetch an argument */
- extern struct node *xlevarg(); /* fetch and evaluate an argument */
- extern struct node *xlmatch(); /* fetch an typed argument */
- extern struct node *xlevmatch(); /* fetch and evaluate a typed arg */
- extern struct node *xlsend(); /* send a message to an object */
- extern struct node *xlenter(); /* enter a symbol */
- extern struct node *xlsenter(); /* enter a symbol with a static pname */
- extern struct node *xlintern(); /* intern a symbol */
- extern struct node *xlmakesym(); /* make an uninterned symbol */
- extern struct node *xlsave(); /* generate a stack frame */
- extern struct node *xlobsym(); /* find an object's class or instance
- variable */
- extern struct node *xlgetprop(); /* get the value of a property */
- extern char *xlsymname(); /* get the print name of a symbol */
-
- extern struct node *newnode(); /* allocate a new node */
- extern char *stralloc(); /* allocate string space */
- extern char *strsave(); /* make a safe copy of a string */
-
- SHAR_EOF
- if test 8406 -ne "`wc -c < 'xlisp.h'`"
- then
- echo shar: error transmitting "'xlisp.h'" '(should have been 8406 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'xlsetf.c'" '(1884 characters)'
- if test -f 'xlsetf.c'
- then
- echo shar: will not over-write existing file "'xlsetf.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'xlsetf.c'
- /* xlsetf - set field function */
-
- #include "xlisp.h"
-
- /* external variables */
- extern NODE *s_car,*s_cdr,*s_get,*s_svalue,*s_splist;
- extern NODE *xlstack;
-
- /* xsetf - built-in function 'setf' */
- NODE *xsetf(args)
- NODE *args;
- {
- NODE *oldstk,arg,place,value;
-
- /* create a new stack frame */
- oldstk = xlsave(&arg,&place,&value,NULL);
-
- /* initialize */
- arg.n_ptr = args;
-
- /* handle each pair of arguments */
- while (arg.n_ptr) {
-
- /* get place and value */
- place.n_ptr = xlarg(&arg.n_ptr);
- value.n_ptr = xlevarg(&arg.n_ptr);
-
- /* check the place form */
- if (symbolp(place.n_ptr))
- assign(place.n_ptr,value.n_ptr);
- else if (consp(place.n_ptr))
- placeform(place.n_ptr,value.n_ptr);
- else
- xlfail("bad place form");
- }
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the value */
- return (value.n_ptr);
- }
-
- /* placeform - handle a place form other than a symbol */
- LOCAL placeform(place,value)
- NODE *place,*value;
- {
- NODE *fun,*oldstk,arg1,arg2;
-
- /* check the function name */
- if ((fun = xlmatch(SYM,&place)) == s_get) {
- oldstk = xlsave(&arg1,&arg2,NULL);
- arg1.n_ptr = xlevmatch(SYM,&place);
- arg2.n_ptr = xlevmatch(SYM,&place);
- xllastarg(place);
- xlputprop(arg1.n_ptr,value,arg2.n_ptr);
- xlstack = oldstk;
- }
- else if (fun == s_svalue || fun == s_splist) {
- oldstk = xlsave(&arg1,NULL);
- arg1.n_ptr = xlevmatch(SYM,&place);
- xllastarg(place);
- if (fun == s_svalue)
- arg1.n_ptr->n_symvalue = value;
- else
- rplacd(arg1.n_ptr->n_symplist,value);
- xlstack = oldstk;
- }
- else if (fun == s_car || fun == s_cdr) {
- oldstk = xlsave(&arg1,NULL);
- arg1.n_ptr = xlevmatch(LIST,&place);
- xllastarg(place);
- if (consp(arg1.n_ptr))
- if (fun == s_car)
- rplaca(arg1.n_ptr,value);
- else
- rplacd(arg1.n_ptr,value);
- xlstack = oldstk;
- }
- else
- xlfail("bad place form");
- }
- SHAR_EOF
- if test 1884 -ne "`wc -c < 'xlsetf.c'`"
- then
- echo shar: error transmitting "'xlsetf.c'" '(should have been 1884 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'xlstr.c'" '(4134 characters)'
- if test -f 'xlstr.c'
- then
- echo shar: will not over-write existing file "'xlstr.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'xlstr.c'
- /* xlstr - xlisp string builtin functions */
-
- #include "xlisp.h"
-
- /* external variables */
- extern NODE *xlstack;
-
- /* external procedures */
- extern char *strcat();
-
- /* xstrlen - length of a string */
- NODE *xstrlen(args)
- NODE *args;
- {
- NODE *val;
- int total;
-
- /* initialize */
- total = 0;
-
- /* loop over args and total */
- while (args)
- total += strlen(xlmatch(STR,&args)->n_str);
-
- /* create the value node */
- val = newnode(INT);
- val->n_int = total;
-
- /* return the total */
- return (val);
- }
-
- /* xstrcat - concatenate a bunch of strings */
- NODE *xstrcat(args)
- NODE *args;
- {
- NODE *oldstk,val,*p;
- char *str;
- int len;
-
- /* create a new stack frame */
- oldstk = xlsave(&val,NULL);
-
- /* find the length of the new string */
- for (p = args, len = 0; p; )
- len += strlen(xlmatch(STR,&p)->n_str);
-
- /* create the result string */
- val.n_ptr = newnode(STR);
- val.n_ptr->n_str = str = stralloc(len);
- *str = 0;
-
- /* combine the strings */
- while (args)
- strcat(str,xlmatch(STR,&args)->n_str);
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the new string */
- return (val.n_ptr);
- }
-
- /* xsubstr - return a substring */
- NODE *xsubstr(args)
- NODE *args;
- {
- NODE *oldstk,arg,src,val;
- int start,forlen,srclen;
- char *srcptr,*dstptr;
-
- /* create a new stack frame */
- oldstk = xlsave(&arg,&src,&val,NULL);
-
- /* initialize */
- arg.n_ptr = args;
-
- /* get string and its length */
- src.n_ptr = xlmatch(STR,&arg.n_ptr);
- srcptr = src.n_ptr->n_str;
- srclen = strlen(srcptr);
-
- /* get starting pos -- must be present */
- start = xlmatch(INT,&arg.n_ptr)->n_int;
-
- /* get length -- if not present use remainder of string */
- forlen = (arg.n_ptr ? xlmatch(INT,&arg.n_ptr)->n_int : srclen);
-
- /* make sure there aren't any more arguments */
- xllastarg(arg.n_ptr);
-
- /* don't take more than exists */
- if (start + forlen > srclen)
- forlen = srclen - start + 1;
-
- /* if start beyond string -- return null string */
- if (start > srclen) {
- start = 1;
- forlen = 0; }
-
- /* create return node */
- val.n_ptr = newnode(STR);
- val.n_ptr->n_str = dstptr = stralloc(forlen);
-
- /* move string */
- for (srcptr += start-1; forlen--; *dstptr++ = *srcptr++)
- ;
- *dstptr = 0;
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the substring */
- return (val.n_ptr);
- }
-
- /* xascii - return ascii value */
- NODE *xascii(args)
- NODE *args;
- {
- NODE *val;
-
- /* build return node */
- val = newnode(INT);
- val->n_int = *(xlmatch(STR,&args)->n_str);
-
- /* make sure there aren't any more arguments */
- xllastarg(args);
-
- /* return the character */
- return (val);
- }
-
- /* xchr - convert an INT into a one character ascii string */
- NODE *xchr(args)
- NODE *args;
- {
- NODE *oldstk,val;
- char *sptr;
-
- /* create a new stack frame */
- oldstk = xlsave(&val,NULL);
-
- /* build return node */
- val.n_ptr = newnode(STR);
- val.n_ptr->n_str = sptr = stralloc(1);
- *sptr++ = xlmatch(INT,&args)->n_int;
- *sptr = 0;
-
- /* make sure there aren't any more arguments */
- xllastarg(args);
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the new string */
- return (val.n_ptr);
- }
-
- /* xatoi - convert an ascii string to an integer */
- NODE *xatoi(args)
- NODE *args;
- {
- NODE *val;
- int n;
-
- /* get the string and convert it */
- n = atoi(xlmatch(STR,&args)->n_str);
-
- /* make sure there aren't any more arguments */
- xllastarg(args);
-
- /* create the value node */
- val = newnode(INT);
- val->n_int = n;
-
- /* return the number */
- return (val);
- }
-
- /* xitoa - convert an integer to an ascii string */
- NODE *xitoa(args)
- NODE *args;
- {
- NODE *val;
- char buf[20];
- int n;
-
- /* get the integer */
- n = xlmatch(INT,&args)->n_int;
- xllastarg(args);
-
- /* convert it to ascii */
- sprintf(buf,"%d",n);
-
- /* create the value node */
- val = newnode(STR);
- val->n_str = strsave(buf);
-
- /* return the string */
- return (val);
- }
- SHAR_EOF
- if test 4134 -ne "`wc -c < 'xlstr.c'`"
- then
- echo shar: error transmitting "'xlstr.c'" '(should have been 4134 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'xlstub.c.XXX'" '(158 characters)'
- if test -f 'xlstub.c.XXX'
- then
- echo shar: will not over-write existing file "'xlstub.c.XXX'"
- else
- sed 's/^X//' << \SHAR_EOF > 'xlstub.c.XXX'
- /* xlstub.c - stubs for replacing the 'xlobj' module */
-
- #include "xlisp.h"
-
- xloinit() {}
- NODE *xlsend() { return (NIL); }
- NODE *xlobsym() { return (NIL); }
-
- SHAR_EOF
- if test 158 -ne "`wc -c < 'xlstub.c.XXX'`"
- then
- echo shar: error transmitting "'xlstub.c.XXX'" '(should have been 158 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'xlsubr.c'" '(4232 characters)'
- if test -f 'xlsubr.c'
- then
- echo shar: will not over-write existing file "'xlsubr.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'xlsubr.c'
- /* xlsubr - xlisp builtin function support routines */
-
- #include "xlisp.h"
-
- /* external variables */
- extern NODE *k_test,*k_tnot,*s_eql;
- extern NODE *xlstack;
-
- /* xlsubr - define a builtin function */
- xlsubr(sname,type,subr)
- char *sname; int type; NODE *(*subr)();
- {
- NODE *sym;
-
- /* enter the symbol */
- sym = xlsenter(sname);
-
- /* initialize the value */
- sym->n_symvalue = newnode(type);
- sym->n_symvalue->n_subr = subr;
- }
-
- /* xlarg - get the next argument */
- NODE *xlarg(pargs)
- NODE **pargs;
- {
- NODE *arg;
-
- /* make sure the argument exists */
- if (!consp(*pargs))
- xlfail("too few arguments");
-
- /* get the argument value */
- arg = car(*pargs);
-
- /* make sure its not a keyword */
- if (symbolp(arg) && *car(arg->n_symplist)->n_str == ':')
- xlfail("too few arguments");
-
- /* move the argument pointer ahead */
- *pargs = cdr(*pargs);
-
- /* return the argument */
- return (arg);
- }
-
- /* xlmatch - get an argument and match its type */
- NODE *xlmatch(type,pargs)
- int type; NODE **pargs;
- {
- NODE *arg;
-
- /* get the argument */
- arg = xlarg(pargs);
-
- /* check its type */
- if (type == LIST) {
- if (arg && ntype(arg) != LIST)
- xlfail("bad argument type");
- }
- else {
- if (arg == NIL || ntype(arg) != type)
- xlfail("bad argument type");
- }
-
- /* return the argument */
- return (arg);
- }
-
- /* xlevarg - get the next argument and evaluate it */
- NODE *xlevarg(pargs)
- NODE **pargs;
- {
- NODE *oldstk,val;
-
- /* create a new stack frame */
- oldstk = xlsave(&val,NULL);
-
- /* get the argument */
- val.n_ptr = xlarg(pargs);
-
- /* evaluate the argument */
- val.n_ptr = xleval(val.n_ptr);
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the argument */
- return (val.n_ptr);
- }
-
- /* xlevmatch - get an evaluated argument and match its type */
- NODE *xlevmatch(type,pargs)
- int type; NODE **pargs;
- {
- NODE *arg;
-
- /* get the argument */
- arg = xlevarg(pargs);
-
- /* check its type */
- if (type == LIST) {
- if (arg && ntype(arg) != LIST)
- xlfail("bad argument type");
- }
- else {
- if (arg == NIL || ntype(arg) != type)
- xlfail("bad argument type");
- }
-
- /* return the argument */
- return (arg);
- }
-
- /* xltest - get the :test or :test-not keyword argument */
- xltest(pfcn,ptresult,pargs)
- NODE **pfcn; int *ptresult; NODE **pargs;
- {
- NODE *arg;
-
- /* default the argument to eql */
- if (!consp(*pargs)) {
- *pfcn = s_eql->n_symvalue;
- *ptresult = TRUE;
- return;
- }
-
- /* get the keyword */
- arg = car(*pargs);
-
- /* check the keyword */
- if (arg == k_test)
- *ptresult = TRUE;
- else if (arg == k_tnot)
- *ptresult = FALSE;
- else
- xlfail("expecting :test or :test-not");
-
- /* move the argument pointer ahead */
- *pargs = cdr(*pargs);
-
- /* make sure the argument exists */
- if (!consp(*pargs))
- xlfail("no value for keyword argument");
-
- /* get the argument value */
- *pfcn = car(*pargs);
-
- /* if its a symbol, get its value */
- if (symbolp(*pfcn))
- *pfcn = xleval(*pfcn);
-
- /* move the argument pointer ahead */
- *pargs = cdr(*pargs);
- }
-
- /* xllastarg - make sure the remainder of the argument list is empty */
- xllastarg(args)
- NODE *args;
- {
- if (args)
- xlfail("too many arguments");
- }
-
- /* assign - assign a value to a symbol */
- assign(sym,val)
- NODE *sym,*val;
- {
- NODE *lptr;
-
- /* check for a current object */
- if ((lptr = xlobsym(sym)) != NIL)
- rplaca(lptr,val);
- else
- sym->n_symvalue = val;
- }
-
- /* eq - internal eq function */
- int eq(arg1,arg2)
- NODE *arg1,*arg2;
- {
- return (arg1 == arg2);
- }
-
- /* eql - internal eql function */
- int eql(arg1,arg2)
- NODE *arg1,*arg2;
- {
- if (eq(arg1,arg2))
- return (TRUE);
- else if (fixp(arg1) && fixp(arg2))
- return (arg1->n_int == arg2->n_int);
- else if (stringp(arg1) && stringp(arg2))
- return (strcmp(arg1->n_str,arg2->n_str) == 0);
- else
- return (FALSE);
- }
-
- /* equal - internal equal function */
- int equal(arg1,arg2)
- NODE *arg1,*arg2;
- {
- /* compare the arguments */
- if (eql(arg1,arg2))
- return (TRUE);
- else if (consp(arg1) && consp(arg2))
- return (equal(car(arg1),car(arg2)) && equal(cdr(arg1),cdr(arg2)));
- else
- return (FALSE);
- }
- SHAR_EOF
- if test 4232 -ne "`wc -c < 'xlsubr.c'`"
- then
- echo shar: error transmitting "'xlsubr.c'" '(should have been 4232 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'xlsym.c'" '(3869 characters)'
- if test -f 'xlsym.c'
- then
- echo shar: will not over-write existing file "'xlsym.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'xlsym.c'
- /* xlsym - symbol handling routines */
-
- #include "xlisp.h"
-
- /* external variables */
- extern NODE *oblist,*keylist;
- extern NODE *s_unbound;
- extern NODE *xlstack;
-
- /* forward declarations */
- XFORWARD NODE *symenter();
- XFORWARD NODE *xlmakesym();
- XFORWARD NODE *findprop();
-
- /* xlenter - enter a symbol into the oblist or keylist */
- NODE *xlenter(name,type)
- char *name;
- {
- return (symenter(name,type,(*name == ':' ? keylist : oblist)));
- }
-
- /* symenter - enter a symbol into a package */
- LOCAL NODE *symenter(name,type,listsym)
- char *name; int type; NODE *listsym;
- {
- NODE *oldstk,*lsym,*nsym,newsym;
- int cmp;
-
- /* check for nil */
- if (strcmp(name,"nil") == 0)
- return (NIL);
-
- /* check for symbol already in table */
- lsym = NIL;
- nsym = listsym->n_symvalue;
- while (nsym) {
- if ((cmp = strcmp(name,xlsymname(car(nsym)))) <= 0)
- break;
- lsym = nsym;
- nsym = cdr(nsym);
- }
-
- /* check to see if we found it */
- if (nsym && cmp == 0)
- return (car(nsym));
-
- /* make a new symbol node and link it into the list */
- oldstk = xlsave(&newsym,NULL);
- newsym.n_ptr = newnode(LIST);
- rplaca(newsym.n_ptr,xlmakesym(name,type));
- rplacd(newsym.n_ptr,nsym);
- if (lsym)
- rplacd(lsym,newsym.n_ptr);
- else
- listsym->n_symvalue = newsym.n_ptr;
- xlstack = oldstk;
-
- /* return the new symbol */
- return (car(newsym.n_ptr));
- }
-
- /* xlsenter - enter a symbol with a static print name */
- NODE *xlsenter(name)
- char *name;
- {
- return (xlenter(name,STATIC));
- }
-
- /* xlmakesym - make a new symbol node */
- NODE *xlmakesym(name,type)
- char *name;
- {
- NODE *oldstk,sym,*str;
-
- /* create a new stack frame */
- oldstk = xlsave(&sym,NULL);
-
- /* make a new symbol node */
- sym.n_ptr = newnode(SYM);
- sym.n_ptr->n_symvalue = (*name == ':' ? sym.n_ptr : s_unbound);
- sym.n_ptr->n_symplist = newnode(LIST);
- rplaca(sym.n_ptr->n_symplist,str = newnode(STR));
- str->n_str = (type == DYNAMIC ? strsave(name) : name);
- str->n_strtype = type;
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the new symbol node */
- return (sym.n_ptr);
- }
-
- /* xlsymname - return the print name of a symbol */
- char *xlsymname(sym)
- NODE *sym;
- {
- return (car(sym->n_symplist)->n_str);
- }
-
- /* xlgetprop - get the value of a property */
- NODE *xlgetprop(sym,prp)
- NODE *sym,*prp;
- {
- NODE *p;
-
- return ((p = findprop(sym,prp)) ? car(p) : NIL);
- }
-
- /* xlputprop - put a property value onto the property list */
- xlputprop(sym,val,prp)
- NODE *sym,*val,*prp;
- {
- NODE *oldstk,p,*pair;
-
- if ((pair = findprop(sym,prp)) == NIL) {
- oldstk = xlsave(&p,NULL);
- p.n_ptr = newnode(LIST);
- rplaca(p.n_ptr,prp);
- rplacd(p.n_ptr,pair = newnode(LIST));
- rplaca(pair,val);
- rplacd(pair,cdr(sym->n_symplist));
- rplacd(sym->n_symplist,p.n_ptr);
- xlstack = oldstk;
- }
- rplaca(pair,val);
- }
-
- /* xlremprop - remove a property from a property list */
- xlremprop(sym,prp)
- NODE *sym,*prp;
- {
- NODE *last,*p;
-
- last = NIL;
- for (p = cdr(sym->n_symplist); consp(p) && consp(cdr(p)); p = cdr(last)) {
- if (car(p) == prp)
- if (last)
- rplacd(last,cdr(cdr(p)));
- else
- rplacd(sym->n_symplist,cdr(cdr(p)));
- last = cdr(p);
- }
- }
-
- /* findprop - find a property pair */
- LOCAL NODE *findprop(sym,prp)
- NODE *sym,*prp;
- {
- NODE *p;
-
- for (p = cdr(sym->n_symplist); consp(p) && consp(cdr(p)); p = cdr(cdr(p)))
- if (car(p) == prp)
- return (cdr(p));
- return (NIL);
- }
-
- /* xlsinit - symbol initialization routine */
- xlsinit()
- {
- /* initialize the oblist */
- oblist = xlmakesym("*oblist*",STATIC);
- oblist->n_symvalue = newnode(LIST);
- rplaca(oblist->n_symvalue,oblist);
-
- /* initialize the keyword list */
- keylist = xlsenter("*keylist*");
-
- /* enter the unbound symbol indicator */
- s_unbound = xlsenter("*unbound*");
- s_unbound->n_symvalue = s_unbound;
- }
- SHAR_EOF
- if test 3869 -ne "`wc -c < 'xlsym.c'`"
- then
- echo shar: error transmitting "'xlsym.c'" '(should have been 3869 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'xlsys.c'" '(3003 characters)'
- if test -f 'xlsys.c'
- then
- echo shar: will not over-write existing file "'xlsys.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'xlsys.c'
- /* xlsys.c - xlisp builtin system functions */
-
- #include "xlisp.h"
-
- /* external variables */
- extern NODE *xlstack;
- extern int anodes;
-
- /* external symbols */
- extern NODE *a_subr,*a_fsubr;
- extern NODE *a_list,*a_sym,*a_int,*a_str,*a_obj,*a_fptr;
- extern NODE *true;
-
- /* xload - direct input from a file */
- NODE *xload(args)
- NODE *args;
- {
- NODE *oldstk,fname,*val;
- int vflag,pflag;
-
- /* create a new stack frame */
- oldstk = xlsave(&fname,NULL);
-
- /* get the file name, verbose flag and print flag */
- fname.n_ptr = xlmatch(STR,&args);
- vflag = (args ? xlarg(&args) != NIL : TRUE);
- pflag = (args ? xlarg(&args) != NIL : FALSE);
- xllastarg(args);
-
- /* load the file */
- val = (xlload(fname.n_ptr->n_str,vflag,pflag) ? true : NIL);
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the status */
- return (val);
- }
-
- /* xgc - xlisp function to force garbage collection */
- NODE *xgc(args)
- NODE *args;
- {
- /* make sure there aren't any arguments */
- xllastarg(args);
-
- /* garbage collect */
- gc();
-
- /* return nil */
- return (NIL);
- }
-
- /* xexpand - xlisp function to force memory expansion */
- NODE *xexpand(args)
- NODE *args;
- {
- NODE *val;
- int n,i;
-
- /* get the new number to allocate */
- n = (args ? xlmatch(INT,&args)->n_int : 1);
- xllastarg(args);
-
- /* allocate more segments */
- for (i = 0; i < n; i++)
- if (!addseg())
- break;
-
- /* return the number of segments added */
- val = newnode(INT);
- val->n_int = i;
- return (val);
- }
-
- /* xalloc - xlisp function to set the number of nodes to allocate */
- NODE *xalloc(args)
- NODE *args;
- {
- NODE *val;
- int n,oldn;
-
- /* get the new number to allocate */
- n = xlmatch(INT,&args)->n_int;
-
- /* make sure there aren't any more arguments */
- xllastarg(args);
-
- /* set the new number of nodes to allocate */
- oldn = anodes;
- anodes = n;
-
- /* return the old number */
- val = newnode(INT);
- val->n_int = oldn;
- return (val);
- }
-
- /* xmem - xlisp function to print memory statistics */
- NODE *xmem(args)
- NODE *args;
- {
- /* make sure there aren't any arguments */
- xllastarg(args);
-
- /* print the statistics */
- stats();
-
- /* return nil */
- return (NIL);
- }
-
- /* xtype - return type of a thing */
- NODE *xtype(args)
- NODE *args;
- {
- NODE *arg;
-
- if (!(arg = xlarg(&args)))
- return (NIL);
-
- switch (ntype(arg)) {
- case SUBR: return (a_subr);
- case FSUBR: return (a_fsubr);
- case LIST: return (a_list);
- case SYM: return (a_sym);
- case INT: return (a_int);
- case STR: return (a_str);
- case OBJ: return (a_obj);
- case FPTR: return (a_fptr);
- default: xlfail("bad node type");
- }
- }
-
- /* xbaktrace - print the trace back stack */
- NODE *xbaktrace(args)
- NODE *args;
- {
- int n;
-
- n = (args ? xlmatch(INT,&args)->n_int : -1);
- xllastarg(args);
- xlbaktrace(n);
- return (NIL);
- }
-
- /* xexit - get out of xlisp */
- NODE *xexit(args)
- NODE *args;
- {
- xllastarg(args);
- exit();
- }
- SHAR_EOF
- if test 3003 -ne "`wc -c < 'xlsys.c'`"
- then
- echo shar: error transmitting "'xlsys.c'" '(should have been 3003 characters)'
- fi
- fi # end of overwriting check
- # End of shell archive
- exit 0
-
-